//
// Copyright 2017 Google Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

// stylelint-disable selector-class-pattern --
// Selector '.mdc-*' should only be used in this project.

@use 'sass:math';
@use '@material/animation/functions';
@use '@material/animation/variables' as animation-variables;
@use '@material/checkbox/functions' as checkbox-functions;
@use '@material/checkbox/variables' as checkbox-variables;
@use '@material/elevation/mixins' as elevation-mixins;
@use '@material/density/functions' as density-functions;
@use '@material/feature-targeting/feature-targeting';
@use '@material/focus-ring/focus-ring';
@use '@material/ripple/ripple';
@use '@material/ripple/ripple-theme';
@use '@material/rtl/rtl';
@use '@material/theme/theme';
@use '@material/touch-target/mixins' as touch-target-mixins;
@use '@material/typography/typography';
@use '@material/shape/mixins' as shape-mixins;
@use '@material/shape/functions' as shape-functions;
@use './variables';
@use '@material/elevation/functions' as elevation-functions;
@use '@material/theme/theme-color';
@use './trailingaction/mixins' as trailing-action-mixins;

$ripple-target: '.mdc-chip__ripple';

@mixin core-styles($query: feature-targeting.all()) {
  @include without-ripple($query: $query);
  @include ripple($query: $query);
}

@mixin without-ripple($query: feature-targeting.all()) {
  $feat-animation: feature-targeting.create-target($query, animation);
  $feat-color: feature-targeting.create-target($query, color);
  $feat-structure: feature-targeting.create-target($query, structure);

  @include leading-icon-color(variables.$icon-color, $query: $query);
  @include trailing-icon-color(variables.$icon-color, $query: $query);
  @include leading-icon-size(variables.$leading-icon-size, $query: $query);
  @include trailing-icon-size(variables.$trailing-icon-size, $query: $query);
  @include trailing-icon-margin($query: $query);
  @include touch-target-mixins.wrapper($query); // COPYBARA_COMMENT_THIS_LINE
  // prettier-ignore
  @include elevation-mixins.overlay-common($query); // COPYBARA_COMMENT_THIS_LINE

  .mdc-chip {
    @include shape-radius(variables.$shape-radius, $query: $query);
    @include fill-color(variables.$fill-color-default, $query: $query);
    @include ink-color-without-ripple_(
      variables.$ink-color-default,
      $query: $query
    );
    @include typography.typography(body2, $query: $query);
    @include density($density-scale: 0, $query: $query);
    @include leading-icon-margin($query: $query);
    @include elevation-mixins.overlay-surface-position($query: $query);
    @include elevation-mixins.overlay-dimensions(100%, $query: $query);

    @include feature-targeting.targets($feat-structure) {
      display: inline-flex;
      // position: relative; already set in mdc-elevation-overlay-surface-position
      align-items: center;
      box-sizing: border-box;
      padding: 0 variables.$horizontal-padding;
      border-width: 0;
      outline: none;
      cursor: pointer;
      -webkit-appearance: none;

      &::-moz-focus-inner {
        padding: 0;
        border: 0;
      }
    }

    &:hover {
      @include feature-targeting.targets($feat-color) {
        @include theme.property(color, on-surface);
      }
    }

    .mdc-chip__touch {
      @include touch-target-mixins.touch-target($query: $query);
    }
  }

  .mdc-chip--exit {
    @include feature-targeting.targets($feat-color) {
      transition: variables.$exit-transition;
    }

    @include feature-targeting.targets($feat-structure) {
      opacity: 0;
    }
  }

  .mdc-chip__overflow {
    @include feature-targeting.targets($feat-structure) {
      text-overflow: ellipsis;
      overflow: hidden;
    }
  }

  .mdc-chip__text {
    @include feature-targeting.targets($feat-structure) {
      white-space: nowrap;
    }
  }

  .mdc-chip__icon {
    @include feature-targeting.targets($feat-structure) {
      border-radius: 50%;
      outline: none;
      vertical-align: middle;
    }
  }

  .mdc-chip__checkmark {
    @include feature-targeting.targets($feat-structure) {
      height: variables.$leading-icon-size;
    }
  }

  .mdc-chip__checkmark-path {
    @include feature-targeting.targets($feat-animation) {
      transition: checkbox-functions.transition-exit(
        stroke-dashoffset,
        variables.$checkmark-animation-delay,
        variables.$checkmark-animation-duration
      );
    }

    @include feature-targeting.targets($feat-structure) {
      stroke-width: 2px;
      stroke-dashoffset: checkbox-variables.$mark-path-length_;
      stroke-dasharray: checkbox-variables.$mark-path-length_;
    }
  }

  .mdc-chip__primary-action:focus {
    @include feature-targeting.targets($feat-structure) {
      outline: none;
    }
  }

  .mdc-chip--selected .mdc-chip__checkmark-path {
    @include feature-targeting.targets($feat-structure) {
      stroke-dashoffset: 0;
    }
  }

  .mdc-chip__icon--leading,
  .mdc-chip__icon--trailing {
    @include feature-targeting.targets($feat-structure) {
      // Make these positioned elements, such that they're stacked above the
      // touch target element (`mdc-chip__touch`), so that clicks reach the
      // icons (e.g. for removable input chips).
      position: relative;
    }
  }

  // Change color of selected choice chips

  .mdc-chip-set--choice {
    .mdc-chip {
      @include selected-ink-color-without-ripple_(primary, $query: $query);
    }

    .mdc-chip--selected {
      @include feature-targeting.targets($feat-color) {
        @include theme.property(background-color, surface);
      }
    }
  }

  // Add leading checkmark to filter chips with no leading icon

  .mdc-chip__checkmark-svg {
    @include feature-targeting.targets($feat-structure) {
      width: 0;
      height: variables.$leading-icon-size;
    }

    @include feature-targeting.targets($feat-animation) {
      transition: width variables.$width-animation-duration
        animation-variables.$standard-curve-timing-function;
    }
  }

  .mdc-chip--selected .mdc-chip__checkmark-svg {
    @include feature-targeting.targets($feat-structure) {
      width: variables.$leading-icon-size;
    }
  }

  // Add leading checkmark to filter chips with a leading icon

  .mdc-chip-set--filter {
    .mdc-chip__icon--leading {
      @include feature-targeting.targets($feat-animation) {
        transition: opacity variables.$opacity-animation-duration linear;
        transition-delay: variables.$leading-icon-delay;
      }

      @include feature-targeting.targets($feat-structure) {
        opacity: 1;
      }

      + .mdc-chip__checkmark {
        @include feature-targeting.targets($feat-animation) {
          transition: opacity variables.$opacity-animation-duration linear;

          // Delay the checkmark transition.
          transition-delay: variables.$checkmark-with-leading-icon-delay;
        }

        @include feature-targeting.targets($feat-structure) {
          opacity: 0;
        }

        .mdc-chip__checkmark-svg {
          @include feature-targeting.targets($feat-animation) {
            transition: width 0ms;
          }
        }
      }
    }

    .mdc-chip--selected .mdc-chip__icon--leading {
      @include feature-targeting.targets($feat-structure) {
        opacity: 0;
      }

      + .mdc-chip__checkmark {
        @include feature-targeting.targets($feat-structure) {
          // This ensures that the checkmark has zero width while the leading icon is still animating.
          width: 0;
          opacity: 1;
        }
      }
    }

    .mdc-chip__icon--leading-hidden.mdc-chip__icon--leading {
      @include feature-targeting.targets($feat-structure) {
        width: 0;
      }

      @include feature-targeting.targets($feat-structure) {
        // This ensures that the leading icon doesn't fade in while the checkmark is fading out.
        opacity: 0;
      }

      + .mdc-chip__checkmark {
        @include feature-targeting.targets($feat-structure) {
          width: variables.$leading-icon-size;
        }
      }
    }
  }
}

@mixin ripple($query: feature-targeting.all()) {
  @include ripple.common($query); // COPYBARA_COMMENT_THIS_LINE
  $feat-structure: feature-targeting.create-target($query, structure);

  .mdc-chip {
    @include ripple.surface($query: $query, $ripple-target: $ripple-target);
    @include ripple.radius-bounded(
      $query: $query,
      $ripple-target: $ripple-target
    );
    @include ink-color-ripple_(variables.$ink-color-default, $query: $query);

    #{$ripple-target} {
      @include ripple.target-common($query: $query);

      @include feature-targeting.targets($feat-structure) {
        overflow: hidden;
      }
    }
  }

  .mdc-chip-set--choice {
    .mdc-chip {
      @include selected-ink-color-ripple_(primary, $query: $query);
    }
  }
}

@mixin set-core-styles($query: feature-targeting.all()) {
  $feat-animation: feature-targeting.create-target($query, animation);
  $feat-structure: feature-targeting.create-target($query, structure);

  @include feature-targeting.targets($feat-animation) {
    @keyframes mdc-chip-entry {
      from {
        transform: scale(0.8);
        opacity: 0.4;
      }

      to {
        transform: scale(1);
        opacity: 1;
      }
    }
  }

  .mdc-chip-set {
    @include set-spacing(8px, $query: $query);

    @include feature-targeting.targets($feat-structure) {
      display: flex;
      flex-wrap: wrap;
      box-sizing: border-box;
    }
  }

  .mdc-chip-set--input .mdc-chip {
    @include feature-targeting.targets($feat-animation) {
      animation: mdc-chip-entry 100ms
        animation-variables.$deceleration-curve-timing-function;
    }
  }
}

@mixin shape-radius(
  $radius,
  $rtl-reflexive: false,
  $density-scale: variables.$density-scale,
  $query: feature-targeting.all()
) {
  $height: density-functions.prop-value(
    $density-config: variables.$density-config,
    $density-scale: $density-scale,
    $property-name: height,
  );

  @include shape-mixins.radius(
    $radius,
    $rtl-reflexive,
    $component-height: $height,
    $query: $query
  );

  #{$ripple-target} {
    @include shape-mixins.radius(
      $radius,
      $rtl-reflexive,
      $component-height: $height,
      $query: $query
    );
  }
}

@mixin fill-color-accessible($color, $query: feature-targeting.all()) {
  $fill-tone: theme-color.tone($color);

  @include fill-color($color, $query: $query);

  @if ($fill-tone == 'dark') {
    @include ink-color(text-primary-on-dark, $query: $query);
    @include selected-ink-color(text-primary-on-dark, $query: $query);
    @include leading-icon-color(text-primary-on-dark, $query: $query);
    @include trailing-icon-color(text-primary-on-dark, $query: $query);
  } @else {
    @include ink-color(text-primary-on-light, $query: $query);
    @include selected-ink-color(text-primary-on-light, $query: $query);
    @include leading-icon-color(text-primary-on-light, $query: $query);
    @include trailing-icon-color(text-primary-on-light, $query: $query);
  }
}

@mixin fill-color($color, $query: feature-targeting.all()) {
  $feat-color: feature-targeting.create-target($query, color);

  @include feature-targeting.targets($feat-color) {
    @include theme.property(background-color, $color);
  }
}

@mixin ink-color($color, $query: feature-targeting.all()) {
  @include ink-color-ripple_($color, $query: $query);
  @include ink-color-without-ripple_($color, $query: $query);
}

@mixin ink-color-without-ripple_($color, $query) {
  $feat-color: feature-targeting.create-target($query, color);

  @include feature-targeting.targets($feat-color) {
    @include theme.property(color, $color);
  }

  &:hover {
    @include feature-targeting.targets($feat-color) {
      @include theme.property(color, $color);
    }
  }
}

@mixin ink-color-ripple_($color, $query) {
  @include ripple-theme.states(
    $color,
    true,
    $query: $query,
    $ripple-target: $ripple-target
  );
}

@mixin selected-ink-color($color, $query: feature-targeting.all()) {
  @include selected-ink-color-ripple_($color, $query: $query);
  @include selected-ink-color-without-ripple_($color, $query: $query);
}

@mixin selected-ink-color-without-ripple_($color, $query) {
  $feat-color: feature-targeting.create-target($query, color);

  &.mdc-chip--selected {
    @include feature-targeting.targets($feat-color) {
      @include theme.property(color, $color);
    }

    @include leading-icon-color($color, $query: $query);

    &:hover {
      @include feature-targeting.targets($feat-color) {
        @include theme.property(color, $color);
      }
    }
  }

  .mdc-chip__checkmark-path {
    @include feature-targeting.targets($feat-color) {
      @include theme.property(stroke, $color);
    }
  }
}

@mixin selected-ink-color-ripple_($color, $query) {
  &.mdc-chip {
    @include ripple-theme.states-selected(
      $color,
      $has-nested-focusable-element: true,
      $query: $query,
      $ripple-target: $ripple-target
    );
  }
}

@mixin outline(
  $width: 1px,
  $style: solid,
  $color: theme-color.prop-value(on-surface),
  $query: feature-targeting.all()
) {
  @include outline-width($width, $query: $query);
  @include outline-style($style, $query: $query);
  @include outline-color($color, $query: $query);
}

@mixin outline-color($color, $query: feature-targeting.all()) {
  $feat-color: feature-targeting.create-target($query, color);

  @include feature-targeting.targets($feat-color) {
    @include theme.property(border-color, $color);
  }
}

@mixin outline-style($style, $query: feature-targeting.all()) {
  $feat-structure: feature-targeting.create-target($query, structure);

  @include feature-targeting.targets($feat-structure) {
    border-style: $style;
  }
}

@mixin outline-width(
  $width,
  $horizontal-padding: variables.$horizontal-padding,
  $query: feature-targeting.all()
) {
  $feat-structure: feature-targeting.create-target($query, structure);

  // Note: Adjust padding to maintain consistent width with non-outlined chips
  $horizontal-padding-value: math.max($horizontal-padding - $width, 0);

  @include feature-targeting.targets($feat-structure) {
    padding-right: $horizontal-padding-value;
    padding-left: $horizontal-padding-value;
    border-width: $width;
  }

  #{$ripple-target} {
    @include feature-targeting.targets($feat-structure) {
      top: -$width;
      left: -$width;
      border: $width solid transparent;
    }
  }
}

@mixin horizontal-padding($padding, $query: feature-targeting.all()) {
  $feat-structure: feature-targeting.create-target($query, structure);

  @include feature-targeting.targets($feat-structure) {
    padding-right: $padding;
    padding-left: $padding;
  }
}

@mixin height($height, $query: feature-targeting.all()) {
  $feat-structure: feature-targeting.create-target($query, structure);

  @include feature-targeting.targets($feat-structure) {
    height: $height;
  }
}

@mixin set-spacing($gap-size, $query: feature-targeting.all()) {
  $feat-structure: feature-targeting.create-target($query, structure);

  @include feature-targeting.targets($feat-structure) {
    padding: math.div($gap-size, 2);
  }

  .mdc-chip {
    @include feature-targeting.targets($feat-structure) {
      margin: math.div($gap-size, 2);
    }
  }

  .mdc-chip--touch {
    @include touch-target-mixins.margin(
      $component-height: variables.$height,
      $query: $query
    );
  }
}

@mixin leading-icon-color(
  $color,
  $opacity: variables.$icon-opacity,
  $query: feature-targeting.all()
) {
  $feat-color: feature-targeting.create-target($query, color);

  .mdc-chip__icon--leading {
    @include feature-targeting.targets($feat-color) {
      color: rgba(theme-color.prop-value($color), $opacity);
    }
  }
}

@mixin trailing-icon-color(
  $color,
  $opacity: variables.$icon-opacity,
  $hover-opacity: variables.$trailing-icon-hover-opacity,
  $focus-opacity: variables.$trailing-icon-focus-opacity,
  $query: feature-targeting.all()
) {
  $feat-color: feature-targeting.create-target($query, color);

  @include trailing-action-mixins.color($color, $query: $query);

  // TODO(b/151980552): Remove the following block
  .mdc-chip__icon--trailing {
    @include feature-targeting.targets($feat-color) {
      color: rgba(theme-color.prop-value($color), $opacity);
    }

    &:hover {
      @include feature-targeting.targets($feat-color) {
        color: rgba(theme-color.prop-value($color), $hover-opacity);
      }
    }

    &:focus {
      @include feature-targeting.targets($feat-color) {
        color: rgba(theme-color.prop-value($color), $focus-opacity);
      }
    }
  }
}

// For customizing icon size, we need to increase specifity to ensure
// overrides apply. Styles defined in the .material-icons CSS class are
// loaded separately, so the order of CSS definitions is not guaranteed.

@mixin leading-icon-size($size, $query: feature-targeting.all()) {
  .mdc-chip__icon.mdc-chip__icon--leading:not(.mdc-chip__icon--leading-hidden) {
    @include icon-size_($size, $query: $query);
  }
}

@mixin trailing-icon-size($size, $query: feature-targeting.all()) {
  @include trailing-action-mixins.size($size, $query: $query);

  // TODO(b/151980552): Remove the following block
  .mdc-chip__icon.mdc-chip__icon--trailing {
    @include icon-size_($size, $query: $query);
  }
}

@mixin icon-size_($size, $query) {
  $feat-structure: feature-targeting.create-target($query, structure);

  @include feature-targeting.targets($feat-structure) {
    width: $size;
    height: $size;
    font-size: $size;
  }
}

@mixin leading-icon-margin(
  $left-margin: variables.$leading-icon-margin-left,
  $right-margin: variables.$leading-icon-margin-right,
  $query: feature-targeting.all()
) {
  $feat-structure: feature-targeting.create-target($query, structure);

  &.mdc-chip--selected .mdc-chip__checkmark,
  .mdc-chip__icon--leading:not(.mdc-chip__icon--leading-hidden) {
    @include feature-targeting.targets($feat-structure) {
      @include rtl.reflexive-property(margin, $left-margin, $right-margin);
    }
  }
}

@mixin trailing-icon-margin(
  $left-margin: variables.$trailing-icon-margin-left,
  $right-margin: variables.$trailing-icon-margin-right,
  $query: feature-targeting.all()
) {
  $feat-structure: feature-targeting.create-target($query, structure);

  @include trailing-action-mixins.horizontal-spacing(
    $left-margin,
    $right-margin,
    $query: $query
  );

  // TODO(b/151980552): Remove the following block
  .mdc-chip__icon--trailing {
    @include feature-targeting.targets($feat-structure) {
      @include rtl.reflexive-property(margin, $left-margin, $right-margin);
    }
  }
}

@mixin elevation-transition($query: feature-targeting.all()) {
  $feat-animation: feature-targeting.create-target($query, animation);

  @include feature-targeting.targets($feat-animation) {
    transition: elevation-functions.transition-value();
  }

  &.mdc-chip--exit {
    @include feature-targeting.targets($feat-animation) {
      transition: elevation-functions.transition-value(),
        variables.$exit-transition;
    }
  }
}

///
/// Sets the density scale for chips.
///
/// @param {Number | String} $density-scale - Density scale value for component.
///     Supported density scale values are `-2`, `-1`, `0`.
///
@mixin density($density-scale, $query: feature-targeting.all()) {
  $height: density-functions.prop-value(
    $density-config: variables.$density-config,
    $density-scale: $density-scale,
    $property-name: height,
  );

  @include height($height, $query: $query);

  @if $density-scale != 0 {
    @include touch-target-reset_($query: $query);
  }
}

///
/// Resets touch target-related styles. This is called from the density mixin to
/// automatically remove the increased touch target, since dense components
/// don't have the same default a11y requirements.
/// @access private
///
@mixin touch-target-reset_($query: feature-targeting.all()) {
  $feat-structure: feature-targeting.create-target($query, structure);

  // Selector is necessary here to override original specificity.
  &.mdc-chip--touch {
    @include feature-targeting.targets($feat-structure) {
      margin-top: 0;
      margin-bottom: 0;
    }
  }

  .mdc-chip__touch {
    @include feature-targeting.targets($feat-structure) {
      display: none;
    }
  }
}

@mixin high-contrast-focus {
  // High contrast mode focus for chips.
  .mdc-chip__focus-ring {
    display: none;
  }

  @include ripple-theme.focus() {
    .mdc-chip__focus-ring {
      z-index: 1;
      display: block;
      @include focus-ring.focus-ring();
    }
  }
}
